// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf

#include "MgcGeometry.h"
#include "MgcRenderer.h"

MgcImplementRTTI(MgcGeometry,MgcSpatial);
MgcImplementStream(MgcGeometry);

//---------------------------------------------------------------------------
MgcGeometry::MgcGeometry (unsigned int uiVertexQuantity,
    MgcVector3* akVertex, MgcVector3* akNormal, MgcColor* akColor,
    MgcVector2* akTexture)
{
    m_uiVertexQuantity = uiVertexQuantity;
    m_akVertex = akVertex;
    m_akNormal = akNormal;
    m_akColor = akColor;
    m_akTexture = akTexture;
}
//---------------------------------------------------------------------------
MgcGeometry::MgcGeometry ()
{
    m_uiVertexQuantity = 0;
    m_akVertex = 0;
    m_akNormal = 0;
    m_akColor = 0;
    m_akTexture = 0;
}
//---------------------------------------------------------------------------
MgcGeometry::~MgcGeometry ()
{
    delete[] m_akVertex;
    delete[] m_akNormal;
    delete[] m_akColor;
    delete[] m_akTexture;
}
//---------------------------------------------------------------------------
void MgcGeometry::Reconstruct (unsigned int uiVertexQuantity)
{
    m_uiVertexQuantity = uiVertexQuantity;

    delete[] m_akVertex;
    delete[] m_akNormal;
    delete[] m_akColor;
    delete[] m_akTexture;


    if ( m_uiVertexQuantity > 0 )
    {
        m_akVertex = new MgcVector3[m_uiVertexQuantity];

        if ( m_akNormal )
            m_akNormal = new MgcVector3[m_uiVertexQuantity];
        else
            m_akNormal = 0;

        if ( m_akColor )
            m_akColor = new MgcColor[m_uiVertexQuantity];
        else
            m_akColor = 0;

        if ( m_akTexture )
            m_akTexture = new MgcVector2[m_uiVertexQuantity];
        else
            m_akTexture = 0;
    }
    else
    {
        m_akVertex = 0;
        m_akNormal = 0;
        m_akColor = 0;
        m_akTexture = 0;
    }
}
//---------------------------------------------------------------------------
void MgcGeometry::Reconstruct (unsigned int uiVertexQuantity,
    MgcVector3* akVertex, MgcVector3* akNormal, MgcColor* akColor,
    MgcVector2* akTexture)
{
    m_uiVertexQuantity = uiVertexQuantity;

    if ( m_akVertex != akVertex )
    {
        delete[] m_akVertex;
        m_akVertex = akVertex;
    }

    if ( m_akNormal != akNormal )
    {
        delete[] m_akNormal;
        m_akNormal = akNormal;
    }

    if ( m_akColor != akColor )
    {
        delete[] m_akColor;
        m_akColor = akColor;
    }

    if ( m_akTexture != akTexture )
    {
        delete[] m_akTexture;
        m_akTexture = akTexture;
    }
}
//---------------------------------------------------------------------------
void MgcGeometry::UpdateModelBound ()
{
    m_kBound.ComputeFromData(m_uiVertexQuantity,m_akVertex);
}
//---------------------------------------------------------------------------
void MgcGeometry::UpdateWorldBound ()
{
    m_kWorldBound = m_kBound.TransformBy(m_kWorldRotate,m_kWorldTranslate,
        m_fWorldScale);
}
//---------------------------------------------------------------------------
void MgcGeometry::UpdateModelNormals ()
{
    // stub for derived clases
}
//---------------------------------------------------------------------------
void MgcGeometry::UpdateRenderState (MgcRenderState* apkState[])
{
    for (unsigned int uiI = 0; uiI < MgcRenderState::RS_MAX_STATE; uiI++)
        m_aspkState[uiI] = apkState[uiI]->Copy();
}
//---------------------------------------------------------------------------
void MgcGeometry::Draw (MgcRenderer& rkRenderer)
{
    rkRenderer.SetState(m_aspkState);
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// streaming
//---------------------------------------------------------------------------
MgcObject* MgcGeometry::Factory (MgcStream& rkStream)
{
    // MgcGeometry is abstract, Factory never called
    return 0;
}
//---------------------------------------------------------------------------
void MgcGeometry::Load (MgcStream& rkStream, MgcStream::Link* pkLink)
{
    MgcSpatial::Load(rkStream,pkLink);

    // native data
    MgcStreamRead(rkStream,m_uiVertexQuantity);
    m_akVertex = new MgcVector3[m_uiVertexQuantity];
    MgcStreamRead(rkStream,m_akVertex,m_uiVertexQuantity);

    MgcStreamRead(rkStream,m_akNormal);
    if ( m_akNormal )
    {
        m_akNormal = new MgcVector3[m_uiVertexQuantity];
        MgcStreamRead(rkStream,m_akNormal,m_uiVertexQuantity);
    }

    MgcStreamRead(rkStream,m_akColor);
    if ( m_akColor )
    {
        m_akColor = new MgcColor[m_uiVertexQuantity];
        MgcStreamRead(rkStream,m_akColor,m_uiVertexQuantity);
    }

    MgcStreamRead(rkStream,m_akTexture);
    if ( m_akTexture )
    {
        m_akTexture = new MgcVector2[m_uiVertexQuantity];
        MgcStreamRead(rkStream,m_akTexture,m_uiVertexQuantity);
    }

    MgcStreamRead(rkStream,m_kBound);
}
//---------------------------------------------------------------------------
void MgcGeometry::Link (MgcStream& rkStream, MgcStream::Link* pkLink)
{
    MgcSpatial::Link(rkStream,pkLink);
}
//---------------------------------------------------------------------------
bool MgcGeometry::Register (MgcStream& rkStream)
{
    return MgcSpatial::Register(rkStream);

    // render state array is derived, no need to register
}
//---------------------------------------------------------------------------
void MgcGeometry::Save (MgcStream& rkStream)
{
    MgcSpatial::Save(rkStream);

    // native data
    MgcStreamWrite(rkStream,m_uiVertexQuantity);
    MgcStreamWrite(rkStream,m_akVertex,m_uiVertexQuantity);

    MgcStreamWrite(rkStream,m_akNormal);
    if ( m_akNormal )
        MgcStreamWrite(rkStream,m_akNormal,m_uiVertexQuantity);

    MgcStreamWrite(rkStream,m_akColor);
    if ( m_akColor )
        MgcStreamWrite(rkStream,m_akColor,m_uiVertexQuantity);

    MgcStreamWrite(rkStream,m_akTexture);
    if ( m_akTexture )
        MgcStreamWrite(rkStream,m_akTexture,m_uiVertexQuantity);

    MgcStreamWrite(rkStream,m_kBound);

    // render state array is derived, no need to save
}
//---------------------------------------------------------------------------
